/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package util;


import exception.SamegameIOException;
import java.io.*;
import java.util.Scanner;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * this thingy should be a threadsafe filewriter
 * and is the global reader (not threadsafe, 'cause not needed)
 * 
 * mag umstaendlich erscheinen, den filereader hier drin zu verschachteln
 * aber zur not kann man am ende beliebig modifizieren, falls es
 * aufgrund auftretender nebenbedingungen noetig sein sollte
 * --> ansonsten mittels getReader() den reader quasi direkt bedienen
 * @author bomik
 */
public class IOutil {
    
    static final String LOGFILE = "samegame.log";
    static final String OUTFILE = "output.txt";
    static String f_input;//Inputfile for reading
    
    private static Scanner in;
    static PrintWriter log;
    private static final Lock logLock = new ReentrantLock();
    static PrintWriter out;
    private static final Lock outLock = new ReentrantLock();
    static IOutil instance;
    
    public static void setInputFile(String path){
        File f = new File(path);
        if(!f.exists()||!f.canRead()) {
            throw new SamegameIOException("cant read from "+path+((f.exists())? ": no readacess" : ": file not exists"));
        }
        f_input=path;
        if(in!=null) {
            in.close();
        }
    }
    /**
     * use instead of manually creating new FileReader-object
     * be sure to set a proper inputufile before
     */
    public static void startReading(){
        if(in!=null) {
            in.close();
        }
        try {
            in=new Scanner(new File(f_input));
        } catch (FileNotFoundException ex) {
            throw new SamegameIOException("can't create Scanner from file "+f_input);
        }
    }
    public static Scanner getReader(){
        if(in!=null) {
            return in;
        }
        else {
            throw new SamegameIOException("start reading first!");
        }
    }
    /**
     * use this instead of IOutil.in.close()
     * closes the filereader and set it to null
     * if filereader is already null, nothing happens
     */
    public static void stopReading(){
        if(in!=null){
            in.close();
            in=null;
        }
    }
    
    //<editor-fold defaultstate="collapsed" desc="methods for writing">
    public static void writeOutLine(Object o){
        if(o!=null){
            outLock.lock();
            try {
                out.write(o.toString() + "\n");
            } finally {
                outLock.unlock();
            }
        }
    }
    public static void writeLogLine(Object o){
        if(o!=null){
            logLock.lock();
            try {
                log.write(o.toString() + "\n");
            } finally {
                logLock.unlock();
            }
        }
    }
    /**
     * maybe not needed
     */
    public static void flush(){
        outLock.lock();
        logLock.lock();
        try {
            if (out.checkError() || log.checkError()) {
                throw new SamegameIOException("Logging nicht moeglich");
            }
        } finally {
            outLock.unlock();
            logLock.unlock();
        }
    }
    //</editor-fold>
    //<editor-fold defaultstate="collapsed" desc="make it threadsafe!">
    private IOutil(){
        try {
            out = new PrintWriter(new FileWriter(OUTFILE));
            log = new PrintWriter(new FileWriter(LOGFILE));
        } catch (IOException ex) {
            throw new SamegameIOException("Filewriting nicht moeglich: "+ex.getMessage(),ex.fillInStackTrace());
        }
    }
    public static IOutil getInstance(){
        synchronized(IOutil.class){
            if(instance==null){
                instance = new IOutil();
            }
        }
        return instance;
    }
    //</editor-fold>
    
}
